package solutions.leetcode.hard

/**
 * @author lizhidong
 * <a href="https://leetcode.cn/problems/dice-roll-simulation/">1223. 掷骰子模拟</a>
 */
private class Solution1233 {
    val mod = 1000000007

    fun dieSimulator(n: Int, rollMax: IntArray): Int {
        var array = Array(6) { hashMapOf(Pair(1L, 1L)) }
        var t = 1
        while (t++ < n) {
            val next = Array(6) { HashMap<Long, Long>() }
            for (i in 0 until 6) {
                for (j in 0 until 6) {
                    if (i == j) {
                        val okMap = array[j].filter { it.key < rollMax[j] }
                        for (item in okMap) {
                            next[i][item.key + 1] = item.value
                        }
                    } else {
                        val v1 = (next[i].getOrDefault(1, 0) + array[j].toList().sumOf { it.second }) % mod
                        next[i][1] = v1
                    }
                }
            }
            array = next
        }
        return (array.map { it.toList() }.toList().sumOf { it -> it.sumOf { it.second } } % mod).toInt()
    }

    inline fun <T> Iterable<T>.sumOf(selector: (T) -> Long): Long {
        var sum: Long = 0.toLong()
        for (element in this) {
            sum += selector(element)
            sum %= mod
        }
        return sum
    }
}

fun main() {
    println(
        Solution1233().dieSimulator(
            3, intArrayOf(
                1, 1, 1, 2, 2, 3
            )
        )
    )
}